// 此前我们实现了提取函数的首个参数类型：
type FunctionType = (...args: any[]) => any

type FirstParameter<T extends FunctionType> = T extends (arg: infer P, ...args: any) => any ? P : never
// --test
type FirstParameter_test1 = FirstParameter<(name: string, age: number) => any>

// 要提取最后一个参数类型则可以这样：
// !注意这里的 (arg:infer P) 需要写且要放在前面,是为了下面测试的第二种情况的 有可能参数只有一个那么就是这个infer P 类型 ,也有可能所有参数都是infer P 类型
type LastParameter<T extends FunctionType> = T extends (arg: infer P) => any ? P : T extends (...args: infer R) => any ? (R extends [...any, infer Q] ? Q : never) : never

type FuncFoo = (arg: number) => void
type FuncBar = (...args: string[]) => void
type FuncBaz = (arg1: string, arg2: boolean) => void
type FooLastParameter = LastParameter<FuncFoo> // number
type BarLastParameter = LastParameter<FuncBar> // string
type BazLastParameter = LastParameter<FuncBaz> // boolean

//曾经讲到一个提取 Promise 内部值类型的工具类型 PromiseValue， TypeScript 内置工具类型中也存在这么一个作用的工具类型，并且它的实现要更为严谨：

type Awaited1<T> = T extends null | undefined ? T : T extends object & { then(onfulfilled: infer F): any } ? (F extends (value: infer V, ...args: any) => any ? Awaited1<V> : never) : T
